package cn.yx.framework.configuration;


import cn.yx.framework.error.ServerExceptionHandler;
import org.hibernate.validator.HibernateValidator;
import org.springframework.boot.autoconfigure.web.DefaultErrorAttributes;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.context.request.RequestAttributes;

import java.util.Map;

/**
 * 视图层配置
 *
 * @author chenw
 * @create 2016-12-29 14:27
 * @email javacspring@gmail.com
 */
@Configuration
class ViewConfig {

    private static final int MAX_UPLOAD_SIZE = 5 * 1024 * 1024; // 5 MB

    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return (container -> {
            ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error");
            ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/error");
            ErrorPage error405Page = new ErrorPage(HttpStatus.METHOD_NOT_ALLOWED, "/error");
            ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error");
            ErrorPage error503Page = new ErrorPage(HttpStatus.SERVICE_UNAVAILABLE, "/error");
            container.addErrorPages(error401Page, error404Page, error405Page, error500Page, error503Page);
        });
    }

    @Bean
    public DefaultErrorAttributes errorAttributes() {
        return new DefaultErrorAttributes() {
            @Override
            public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
                Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace);
                errorAttributes.remove("error");
                errorAttributes.remove("exception");
                return errorAttributes;
            }
        };
    }

    @Bean
    public ServerExceptionHandler errorController() {
        return new ServerExceptionHandler();
    }

    @Bean(name = "messageSource")
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("i18n/messages");
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.setCacheMillis(10000);
        messageSource.setUseCodeAsDefaultMessage(false);
        return messageSource;
    }

    @Bean
    public ReloadableResourceBundleMessageSource validateMessage() {
        ReloadableResourceBundleMessageSource validateMessage = new ReloadableResourceBundleMessageSource();
        validateMessage.setBasename("classpath:i18n/validation");
        validateMessage.setUseCodeAsDefaultMessage(false);
        validateMessage.setDefaultEncoding("utf-8");
        validateMessage.setCacheSeconds(1);
        return validateMessage;
    }

    @Bean
    public ConfigurableWebBindingInitializer webBindingInitializer() {
        ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
        initializer.setValidator(localValidatorFactoryBean());
        return initializer;
    }

    @Bean
    public LocalValidatorFactoryBean localValidatorFactoryBean() {
        LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
        validator.setProviderClass(HibernateValidator.class);
        validator.setValidationMessageSource(validateMessage());
        return validator;
    }
}
